﻿namespace Raven
{
    public class GoalMoveToPosition : GoalComposite<RavenBot>
    {
        //the position the bot wants to reach
        private Vector2 _destination;

        public GoalMoveToPosition(RavenBot owner, Vector2 pos) : base(owner, GoalType.goal_move_to_position)
        {
            _destination = pos;
        }

        public override void Activate()
        {
            _status = GoalStatus.active;

            //make sure the subgoal list is clear.
            RemoveAllSubgoals();

            //requests a path to the target position from the path planner. Because, for
            //demonstration purposes, the Raven path planner uses time-slicing when 
            //processing the path requests the bot may have to wait a few update cycles
            //before a path is calculated. Consequently, for appearances sake, it just
            //seeks directly to the target position whilst it's awaiting notification
            //that the path planning request has succeeded/failed
            if (_owner.GetPathPlanner().RequestPathToPosition(_destination))
            {
                AddSubgoal(new GoalSeekToPosition(_owner, _destination));
            }
        }

        public override GoalStatus Process()
        {
            //if status is inactive, call Activate()
            ActivateIfInactive();

            //process the subgoals
            _status = ProcessSubgoals();

            //if any of the subgoals have failed then this goal re-plans
            ReactivateIfFailed();

            return _status;
        }

        //---------------------------- HandleMessage ----------------------------------
        //-----------------------------------------------------------------------------
        public override bool HandleMessage(Telegram msg)
        {
            //first, pass the message down the goal hierarchy
            bool bHandled = ForwardMessageToFrontMostSubgoal(msg);

            //if the msg was not handled, test to see if this goal can handle it
            if (bHandled == false)
            {
                switch (msg.msg)
                {
                    case MessageType.Msg_PathReady:

                        //clear any existing goals
                        RemoveAllSubgoals();

                        AddSubgoal(new GoalFollowPath(_owner,
                            _owner.GetPathPlanner().GetPath()));

                        return true; //msg handled


                    case MessageType.Msg_NoPathAvailable:

                        _status = GoalStatus.failed;

                        return true; //msg handled

                    default: return false;
                }
            }

            //handled by subgoals
            return true;
        }

        public override void Terminate()
        {
        }
    }
}